package com.lin.cloud.disk.manage.impl;

import cn.hutool.json.JSONUtil;
import com.alipay.easysdk.factory.Factory;
import com.alipay.easysdk.payment.app.models.AlipayTradeAppPayResponse;
import com.alipay.easysdk.payment.common.models.AlipayTradeQueryResponse;
import com.alipay.easysdk.payment.common.models.AlipayTradeRefundResponse;
import com.alipay.easysdk.payment.page.models.AlipayTradePagePayResponse;
import com.alipay.easysdk.payment.wap.models.AlipayTradeWapPayResponse;
import com.lin.cloud.disk.common.constant.RedisConstant;
import com.lin.cloud.disk.common.exception.BusinessException;
import com.lin.cloud.disk.common.utils.DateUtils;
import com.lin.cloud.disk.entity.pojo.Company;
import com.lin.cloud.disk.entity.request.CreateAliPayRequest;
import com.lin.cloud.disk.manage.IAlipayManageService;
import com.lin.cloud.disk.service.ICompanyService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @program: cloud-disk
 * @description: 阿里支付服务类
 * @author: Lin
 * @create: 2021-03-11 00:21
 **/
@Slf4j
@Service
public class AlipayServiceManageImpl implements IAlipayManageService {

    // 支付成功后要跳转的页面
    @Value("${alipay.returnUrl}")
    private String returnUrl;

    @Value("${alipay.errorUrl}")
    private String errorUrl;

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Resource
    private ICompanyService companyService;

    @Override
    public String page(CreateAliPayRequest request) {
        try {
            Long companyId = request.getUserDTO().getCompanyId();
            String companyJson = stringRedisTemplate.opsForValue().get(RedisConstant.AVAILABLE_COMPANY + companyId);
            Company company = null;
            if (StringUtils.isNotBlank(companyJson)) {
                company = JSONUtil.toBean(companyJson, Company.class);
            }
            if (null == company){
                company = companyService.findById(companyId);
            }
            if (null == company){
                throw new BusinessException("企业不存在,请检查");
            }
            AlipayTradePagePayResponse response = Factory.Payment
                    // 选择电脑网站
                    .Page()
                    // 调用支付方法(订单名称, 商家订单号, 金额, 成功页面)
                    .pay(company.getCompanyName() + "续费订单",
                            DateUtils.date2Str(new Date(), "yyyyMMddHHmmss") + "_" +companyId.toString(), request.getTotal(),
                            returnUrl);
            return response.body;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public String wap(CreateAliPayRequest request) {
        try {
            Long companyId = request.getUserDTO().getCompanyId();
            String companyJson = stringRedisTemplate.opsForValue().get(RedisConstant.AVAILABLE_COMPANY + companyId);
            Company company = null;
            if (StringUtils.isNotBlank(companyJson)) {
                company = JSONUtil.toBean(companyJson, Company.class);
            }
            if (null == company){
                company = companyService.findById(companyId);
            }

            if (null == company){
                throw new BusinessException("企业不存在,请检查");
            }
            AlipayTradeWapPayResponse response = Factory.Payment
                    //选择手机网站
                    .Wap()
                    // 调用支付方法(订单名称, 商家订单号, 金额, 中途退出页面, 成功页面)
                    .pay(company.getCompanyName() + "续费订单", DateUtils.date2Str(new Date(), "yyyyMMddHHmmss") + "_" +companyId.toString(), request.getTotal(), errorUrl, returnUrl);

            return response.body;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "付款失败";
    }

    @Override
    public String refund(String outTradeNo, String refundAmount) {
        try {
            AlipayTradeRefundResponse response = Factory.Payment
                    .Common()
                    // 调用交易退款(商家订单号, 退款金额)
                    .refund(outTradeNo, refundAmount);
            if ("Success".equals(response.getMsg())) {
                return "退款成功";
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "退款失败";
    }

    @Override
    public String app(String subject, String total) {
        try {
            AlipayTradeAppPayResponse response = Factory.Payment.App().pay(subject, "1", total);
            return response.body;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public String getTrade(String outTradeNo) {
        AlipayTradeQueryResponse query = null;
        try {
            query = Factory.Payment.Common().query(outTradeNo);
            String httpBody = query.getHttpBody();
            if ("10000".equals(query.getCode())) {
                return httpBody;
            } else {
                return query.getMsg() + query.getSubMsg();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "failed";
    }

    @Override
    public String downloadBill(String billType, String billDate) {
        return "";
    }


    /**
     * 支付沙箱回调
     * @param params
     */
    @Override
    public void payNotice(Map<String, String> params){
        log.info("交易名称: " + params.get("subject"));
        log.info("交易状态: " + params.get("trade_status"));
        log.info("支付宝交易凭证号: " + params.get("trade_no"));
        log.info("商户订单号: " + params.get("out_trade_no"));
        log.info("交易金额: " + params.get("total_amount"));
        log.info("买家在支付宝唯一id: " + params.get("buyer_id"));
        log.info("买家付款时间: " + params.get("gmt_payment"));
        log.info("买家付款金额: " + params.get("buyer_pay_amount"));
        // 支付成功 根据支付金额刷新公司云盘时间
        // 获取公司id
        String companyId = params.get("out_trade_no").split("_")[1];
        // 获取支付金额
        Integer price =  Double.valueOf(params.get("total_amount")).intValue();
        // 根据支付金额推算续费时间
        Integer addDay = price * 2;
        // 获取公司信息
        Company company = companyService.findById(Long.valueOf(companyId));
        // 获取结束时间
        Date endTime = company.getEndTime();
        Date nowTime = new Date();
        Calendar dd = Calendar.getInstance();
        if (endTime.getTime() >= nowTime.getTime()){
            // 如果公司云盘结束时间大于当前商家 则在结束时间上加addDay
            dd.setTime(endTime);
        }else{
            // 当前时间加上addDay
            dd.setTime(nowTime);
        }
        dd.add(Calendar.DATE, addDay);
        Date time = dd.getTime();
        company.setEndTime(time);
        // 如果是过期 则重置为已生效
        if (3 == company.getStatus()){
            company.setStatus(1);
        }
        // 如果更新成功 更新缓存
        if (companyService.updateById(company) > 0){
            Long expireTime = (company.getEndTime().getTime() - System.currentTimeMillis()) / 1000;
            stringRedisTemplate.opsForValue().set(RedisConstant.AVAILABLE_COMPANY + companyId, JSONUtil.toJsonStr(company), expireTime, TimeUnit.MILLISECONDS);
            log.info(company.getCompanyName() + "续费成功");
        }

    }
}
